import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_rider/main/widgets/ext/u_button.dart';
import 'package:flutter_rider/utils/log.dart';
import 'package:flutter_rider/utils/screen_fit.dart';
import 'package:flutter_svg/svg.dart';
import '../../../api/api.dart';
import '../../../generated/r.dart';
import '../../../module/login/page/login_page.dart';
import '../../../utils/alib.dart';
import '../../../utils/tip.dart';
import '../../../main/widgets/ui_constant.dart';
import '../ext/u_text.dart';
import 'layout.dart';

class RefreshableLayoutController {
  RefreshableLayoutState? _state;
  _attatch(RefreshableLayoutState state) {
    _state = state;
  }

  _dettach() {
    _state = null;
  }

  reload() {
    _state?.reload();
  }
}

class RefreshableLayout extends StatefulWidget {
  Widget Function(dynamic, int) itemBuilder;
  Widget? topWidget;
  String url;
  String Function()? urlCallback;
  bool onlyOnePage;
  String preUrl;
  DataCallback? preDataCallback;
  DataCallback? dataCallback;

  ///处理数据转模型
  HandleDataCallback? handleDataCallback;

  ///这里用来处理某些接口需要列表第一个模型的数据信息
  Function(dynamic data, bool isRefresh)? singleDataCallback;
  RefreshableLayoutController? controller;
  bool lazyLoad;
  RefreshableLayout({
    Key? key,
    required this.itemBuilder,
    this.url = "",
    this.urlCallback,
    this.preUrl = "",
    this.onlyOnePage = false,
    this.topWidget,
    this.preDataCallback,
    this.dataCallback,
    this.handleDataCallback,
    this.singleDataCallback,
    this.controller,
    this.lazyLoad = false,
  }) : super(key: key);

  @override
  State createState() => RefreshableLayoutState();
}

class RefreshableLayoutState extends State<RefreshableLayout> {
  LayoutState layoutState = LayoutState.Loading;
  final _data = [];
  final ScrollController _scrollController = ScrollController();
  int _page = 1;
  var _footerState = FooterState.Loading;
  var _isLoading = false;
  Widget? _customChild;

  @override
  void initState() {
    super.initState();
    widget.controller?._attatch(this);
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        if (_footerState != FooterState.NoMore) {
          //加载更多 上拉刷新
          loadData(false);
          if (widget.singleDataCallback != null) {
            if (_data.isNotEmpty) {
              widget.singleDataCallback!(_data.first, true);
            }
          }
        }
      }
    });
    if (!widget.lazyLoad) {
      //下拉刷新
      loadData(true);
      if (widget.singleDataCallback != null) {
        widget.singleDataCallback!(0, false);
      }
    }
  }

  @override
  void dispose() {
    super.dispose();
    _scrollController.dispose();
    widget.controller?._dettach();
  }

  reload() {
    _data.clear();
    setState(() {
      layoutState = LayoutState.Loading;
    });
    loadData(true);
  }

  showCustomView(Widget? child) {
    _customChild = child;
  }

  loadData(bool top) async {
    if (_isLoading) {
      return;
    }
    var value = await Alib.hasNetwork();
    if (value) {
      _isLoading = true;
      if (widget.preUrl.isNotEmpty) {
        await Api.getSync(widget.preUrl, (data, response) {
          if (data != null) {
            if (widget.preDataCallback != null) {
              widget.preDataCallback!(data);
            }
            _realLoadData(top);
          } else {
            _isLoading = false;
            _showError(response);
          }
        });
      } else {
        await _realLoadData(top);
      }
    } else {
      if (_data.isEmpty) {
        setState(() {
          layoutState = LayoutState.NoNet;
        });
      } else {
        Tip.show("没有网络");
      }
    }
  }

  _realLoadData(bool top) async {
    if (_data.isEmpty) {
      setState(() {
        layoutState = LayoutState.Loading;
      });
    }
    if (top) {
      _page = 1;
    }
    if (!widget.onlyOnePage) {
      _footerState = FooterState.Loading;
    }
    await Api.getSync(_buildUrl(_page), (data, response) {
      _isLoading = false;
      if (data != null) {
        if (widget.dataCallback != null) {
          widget.dataCallback!(data);
        }
        var list = [];
        if (data is List) {
          list = data;
        } else if (data["list"] is List) {
          list = data["list"];
        }
        if (top) {
          _data.clear();
          _footerState = FooterState.Loading;
        }
        if (widget.handleDataCallback != null) {
          try {
            list = widget.handleDataCallback!(list);
          } catch (e) {
            Log.i(e);
          }
        }
        _data.addAll(list);
        if (list.length == 20) {
          _page += 1;
          _footerState = FooterState.Loading;
        } else {
          _footerState = FooterState.NoMore;
        }
        setState(() {
          layoutState = LayoutState.Content;
        });
      } else {
        _showError(response);
      }
    });
  }

  _showError(ServerResponse? response) {
    if (response != null && response.msg.isNotEmpty) {
      // ScaffoldMessenger.of(context).showSnackBar(
      //     SnackBar(content: UText.get(response.msg, Colors.white, 15.rpx)));
      Tip.show(response.msg);
      if(response.code == -100000 || response.code == -100002){
        Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) {
          return LoginPage();
        }), (route) => false);
      }
    }
    if (_data.isEmpty) {
      setState(() {
        layoutState = LayoutState.Error;
      });
    } else {
      if (!widget.onlyOnePage) {
        //footer状态改变
        setState(() {
          _footerState = FooterState.Error;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget content;
    if (layoutState == LayoutState.Loading) {
      content = Center(
        child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
          SizedBox(
            width: 20.rpx,
            height: 20.rpx,
            child: CircularProgressIndicator(
              strokeWidth: 2.rpx,
              color: UIColor.color_t3,
            ),
          ),
          5.hspace,
          UText.getSubText("加载中..."),
        ]),
      );
    } else if (layoutState == LayoutState.Error) {
      content = _renderError();
    } else if (layoutState == LayoutState.NoNet) {
      content = _renderNoNet();
    } else {
      if (_customChild != null) {
        content = _customChild!;
      } else if (_data.isEmpty) {
        content = _renderEmpty();
      } else {
        int length = !widget.onlyOnePage ? _data.length + 1 : _data.length;
        if (widget.topWidget != null) {
          length += 1;
        }
        return RefreshIndicator(
          child: ListView.builder(
              padding: EdgeInsets.only(
                  bottom: MediaQuery.of(context).padding.bottom),
              controller: _scrollController,
              physics: const AlwaysScrollableScrollPhysics(),
              itemCount: length,
              itemBuilder: (context, index) {
                if (widget.topWidget != null) {
                  index -= 1;
                  if (index == -1) {
                    return widget.topWidget!;
                  }
                }
                if (widget.onlyOnePage || index < _data.length) {
                  return widget.itemBuilder(_data[index], index);
                }
                return _renderFooter();
              }),
          onRefresh: _pullToRefresh,
        );
      }
    }
    return LayoutBuilder(
        builder: (BuildContext context, BoxConstraints constraints) {
      return RefreshIndicator(
        onRefresh: _pullToRefresh,
        child: ListView(
          padding:
              EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom),
          physics: const AlwaysScrollableScrollPhysics(),
          children: [
            Column(children: [
              widget.topWidget ?? const SizedBox(),
              SizedBox(
                height: constraints.maxHeight - 0.rpx,
                child: content,
              )
            ]),
          ],
        ),
      );
    });
  }

  Widget _renderEmpty() {
    return SingleChildScrollView(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        64.hspace,
        SvgPicture.asset(R.image_not_data, width: 180.rpx, height: 180.rpx),
        24.hspace,
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            UText.get("暂无数据内容，请", UIColor.color_t3, 16.rpx),
            GestureDetector(
              onTap: () {
                reload();
              },
              child: Text(
                '重新加载',
                style: TextStyle(
                  fontSize: 16.rpx,
                  color: UIColor.color_primary,
                  decoration: TextDecoration.underline,
                  decorationColor: UIColor.color_primary,
                ),
              ),
            ),
          ],
        ),
        24.hspace,
      ],
    ));
  }

  Widget _renderError() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          UText.getSubText("加载失败"),
          10.hspace,
          UButton.getRoundRectButton("重试",
              backgroundColor: UIColor.color_primary,
              fontSize: 13.rpx,
              radius: 2.rpx,
              width: 72.rpx,
              height: 34.rpx, onPressed: () {
            reload();
          })
        ],
      ),
    );
  }

  Widget _renderNoNet() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          SvgPicture.asset(R.image_not_network,
              width: 200.rpx, height: 200.rpx),
          24.hspace,
          Row(mainAxisAlignment: MainAxisAlignment.center, children: [
            UText.get("暂无网络，请", UIColor.color_t3, 16.rpx),
            GestureDetector(
              onTap: () {
                reload();
              },
              child: Text(
                '重新加载',
                style: TextStyle(
                  fontSize: 16.rpx,
                  color: UIColor.color_primary,
                  decoration: TextDecoration.underline,
                  decorationColor: UIColor.color_primary,
                ),
              ),
            )
          ])
        ],
      ),
    );
  }

  Widget _renderFooter() {
    Widget content;
    if (_footerState == FooterState.NoMore) {
      content = Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Icon(Icons.tag_faces, size: 18.rpx, color: Colors.black.withOpacity(0.26)),
          6.wspace,
          UText.get("数据加载完毕", Colors.black.withOpacity(0.26), 12.rpx),
        ],
      );
    } else if (_footerState == FooterState.Error) {
      content = GestureDetector(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(Icons.error_outline, size: 18.rpx, color: UIColor.color_t3),
            6.wspace,
            UText.get("数据加载失败, 点击重试", UIColor.color_t3, 12.rpx),
          ],
        ),
        onTap: () {
          loadData(false);
        },
      );
    } else {
      content = Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          SizedBox(
            width: 18.rpx,
            height: 18.rpx,
            child: CircularProgressIndicator(
              strokeWidth: 1.rpx,
              color: UIColor.color_t3,
            ),
          ),
          6.wspace,
          UText.get("加载中", UIColor.color_t3, 12.rpx),
        ],
      );
    }

    return SizedBox(
      height: 52.rpx,
      width: double.infinity,
      child: Column(
        children: [6.hspace, content, 6.hspace],
      ),
    );
  }

  String _buildUrl(int page) {
    var mapParams = {};
    if (!widget.onlyOnePage) {
      mapParams["page_size"] = "20";
      mapParams["page"] = "$page";
    }
    StringBuffer sb = StringBuffer();
    if (widget.url.isNotEmpty) {
      sb.write(widget.url);
    } else {
      sb.write(widget.urlCallback!());
    }
    if (mapParams.isNotEmpty) {
      String temp = sb.toString();
      if (!temp.contains("?")) {
        sb.write("?");
      } else {
        if (!temp.endsWith("?") || !temp.endsWith("&")) {
          sb.write("&");
        }
      }
    }
    mapParams.forEach((key, value) {
      sb.write(key);
      sb.write("=");
      sb.write(value);
      sb.write("&");
    });
    var temp = sb.toString();
    return temp.substring(0, temp.length - 1);
  }

  Future<void> _pullToRefresh() async {
    await loadData(true);
  }

  @override
  void setState(fn) {
    //重写setState，加一个安全判断，Widget是否安装在tree上
    if (mounted) {
      super.setState(fn);
    }
  }
}
